﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using CoreEx.Common.Extensions;
using CoreEx.Database.Linq.Translators;
using CoreEx.Database.Query.Expressions;
using LinFu.IoC.Configuration;
using System.Reflection;

namespace CoreEx.Database.Linq.Implementation.Translators
{
    [Implements(typeof(IExpressionTranslator_generic<MemberExpression>))]
    public class MemberExpressionTranslatorGeneric : ExpressionTranslatorGenericBase<MemberExpression>
    {
        public MemberExpressionTranslatorGeneric(TranslateResult translateResult) : base(translateResult) {}


        public override DbExpression Translate(MemberExpression expression)
        {
            if (RepresentsEnumerableMember(expression))
                return CreateQueryBasedOnEnumerableMember(expression);
            
            return CreateColumnExpression(expression);
        }

        private DbExpression CreateColumnExpression(MemberExpression expression)
        {
            var tableSource = GetTableSource(expression);
            var columnPrefix = tableSource.Alias;
            var columnName = tableSource.MappedProperties[(PropertyInfo) expression.Member].PropertyMappingInfo.ColumnInfo.ColumnName;
            var columnExpression = ExpressionFactory.Column(columnPrefix, columnName);
            return columnExpression;
        }

        private static bool RepresentsEnumerableMember(MemberExpression memberExpression)
        {
            return memberExpression.Type.IsEnumerable();
        }

        private DbExpression CreateQueryBasedOnEnumerableMember(MemberExpression memberExpression)
        {
            var elementType = memberExpression.Type.GetGenericElementType();
            return CreateQuery(elementType);
        }

    }
}
